package com.atguigu.gmall.item.config;

import com.atguigu.gmall.common.cache.GmallCacheAspect;
import com.atguigu.gmall.common.config.ItemServiceRedissonConfig;
import io.lettuce.core.dynamic.annotation.Value;
import lombok.Data;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 工具类提取的所有自动配置类我们使用@Import即可
 */
@Import({ItemServiceRedissonConfig.class, GmallCacheAspect.class})
//让Spring Boot自己的RedisAutoConfiguration 配置完以后再启动我们的redisson配置
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableAspectJAutoProxy //开启切面功能
@Configuration
public class ItemConfig {

    /**
     * corePoolSize
     * keepAliveTime
     * maximumPoolSize
     * maximumPoolSize
     * workQueue
     * threadFactory 用自己的线程工厂，有uuid
     * RejectedExecutionHandler
     * @return
     */
    @Bean("corePool")
    public ThreadPoolExecutor executor(ThreadConfigProperties properties){
        return new ThreadPoolExecutor(
                properties.core,
                properties.max,
                properties.keepAlive,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(properties.queueLength),
                new MyItemServiceThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
                );
    }

    @Data
    @Component
    @ConfigurationProperties(prefix = "item-service.thread")
    class ThreadConfigProperties{
        private Integer core;
        private Integer max;
        private Long keepAlive;
        private Integer queueLength;
    }
}
